package main

import (
	"fmt"
	"time"
)

/*
*
一、time包简介：
时间和日期是我们开发中常遇到的，Go语发言中的time包提供了时间显示和测量 等所用的函数
二、原理：
时间一把包含时间值和时区
源码：

	type Time struct {
	    wall uint64
	    ext  int64
	    loc *Location
	}

解释：
1.wall： 表示距离公元1年1月1日00:00:00UTC 的秒数；
2.ext： 表示纳秒
3.loc :代表时区，主要处理偏移量，不同的时区，对应的时间不一样。
如何和正确表示时间？
公认最准确的计算应该是使用 “原子震荡周期” 所计算的物理时钟了（Atomic Clock, 也被称为原子钟），这也被定义为标准时间（International Atomic Time）。

而我们常常看见的 UTC（Universal Time Coordinated，世界协调时间）就是利用这种 Atomic Clock 为基准所定义出来的正确时间。
UTC 标准时间是以 GMT（Greenwich Mean Time，格林尼治时间）这个时区为主，所以本地时间与 UTC 时间的时差就是本地时间与 GMT 时间的时差。
UTC + 时区差 = 本地时间
国内使用的一般是北京时间，与UTC的时间关系如下：
UTC + 8个小时 = 北京时间

在Go语言的time 包里面有两个时区变量如下：
time.UTC: UTC时间
time.Local  : 本地时间
同时Go还提供了LoadLocation 方法和FixedZone 方法来获取时区变量，如下：
FixedZone(name string,offset int) *Location
其中 name为时区的名称，offset 是与UTC 之前的时差。
LoadLocation(name string)(*Location,error)
*/

func main() {
	/*
		1.获取当前时间--time.Now()
		我么可以通过time.Now() 函数来获取当前的时间对象，然后通过事件对象来获取当前的时间信息，如下：
	*/
	now := time.Now() //获取当前时间
	fmt.Printf("current time:%v\n", now)

	year := now.Year()     //年
	month := now.Month()   //月
	day := now.Day()       //日
	hour := now.Hour()     //小时
	minute := now.Minute() //分钟
	second := now.Second() //秒
	fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)
	//在时间对象上可以通过调用 Year()、Month()、Day()、Hour()、Minute()、Second()等方法来获取具体的年，月，日，小时，分钟，秒等。

	/**
	2.获取时间戳--Unix()、UnixNano()
	时间戳是1970年1月1日（08：00：00GMT）至当前时间的总毫秒数，他也被称为Unix 时间戳。
	*/

	timestamp1 := now.Unix()     //时间戳
	timestamp2 := now.UnixNano() //纳秒时间戳
	fmt.Printf("现在的时间戳：%v\n", timestamp1)
	fmt.Printf("现在的纳秒时间戳：%v\n", timestamp2)
	/*
		注意：
		首先要通过time.Now() 获取当前的时间对象，然后在时间对象上调用时间戳方法Unix()或者UnixNano()来获取时间戳
	*/

	//使用time.Unix() 函数可以将时间戳转化为时间格式（时间对象）
	timeObj := time.Unix(timestamp1, 0)
	fmt.Println(timeObj)
	fmt.Println(timeObj.Year())
	//通过time.Unix（）函数将时间戳转化为时间对象之后，就又可以在时间对象上调用其他方法了。

	/*
		3.获取当前是星期几-Weekday()
		time 包中的weekday 方法能够返回某个时间节点所对应的是一周中的周几
	*/
	fmt.Println(timeObj.Weekday().String())

	/*
		4.时间操作函数
		Add (可以实现某个时间+时间间隔)
		func (t Time) Add(d Duration) Time  //在时间对象Time 上定义的方法Add,返回一个时间对象
		Add函数可以返回 时间点t + 时间间隔 d 的值。
		需要获取时间点t-d（d为 Duration） 可以使用 t.Add(-d)
	*/
	fmt.Println("当前时间:", timeObj)
	timeObjAfterHour := timeObj.Add(time.Hour)
	fmt.Println("一个小时之后的时间：", timeObjAfterHour)
	/*
			Sub 求两个时间之间的差值：
			func (t Time) Sub (u Time) Duration //在时间对象Time上定义的方法Sub，传入一个时间对象，返回两个时间对象的时间间隔Duration
		返回一个时间端t-u 的值，如果结果超出了Duration 可以表示的最大值或最小值，将返回最大值或最小值。

	*/
	fmt.Println("两个时间的时间差：", timeObjAfterHour.Sub(timeObj))
	/**
	Equal  判断两个时间是否相等：
	func (t Time)Equal(u Time) bool
	Equal 函数会考虑时区的影响，因此不同时区标准的时间也可以正确比较，Equal 方法和 用 t==u 不同，Equal 方法还会比较地点和时区信息
	*/

	/**
	Before 判断一个时间点是否在另外一个时间之前：
	func (t Time) Before(u Time) bool
	如果t代表的时间点在u之前，则返回真，否则返回假。
	*/

	/**
	After   判断一个时间点是否在另外一个时间点之后：
	func (t Time) After(u Time) bool
	如果 t 代表的时间点在 u 之后，则返回真，否则返回假。

	*/

}
